package com.example.tomatotodo.util;

import android.app.AlertDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.tomatotodo.R;
import com.example.tomatotodo.api.ApiClient;
import com.example.tomatotodo.api.ApiService;
import com.example.tomatotodo.model.Result;
import com.example.tomatotodo.model.TodoItem;
import com.example.tomatotodo.model.TodoSettingDTO;
import com.example.tomatotodo.model.TodoSettingSyncDTO;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * 云同步管理器
 * 负责处理与云端数据同步相关的所有功能，包括获取云端设定、上传本地设定等操作
 */
public class CloudSyncManager {
    private static final String TAG = "CloudSyncManager";
    private Context context;
    private AlertDialog syncDialog;
    private AlertDialog detailDialog;

    public CloudSyncManager(Context context) {
        this.context = context;
    }

    /**
     * 获取本地待办事项列表
     *
     * @return 本地待办事项列表
     */
    private List<TodoSettingSyncDTO> getLocalTodoSettings() {
        Log.d(TAG, "getLocalTodoSettings: 获取本地待办事项列表");
        SharedPreferences sharedPreferences = context.getSharedPreferences("todo_data", Context.MODE_PRIVATE);
        String todoListJson = sharedPreferences.getString("todo_list", null);

        List<TodoSettingSyncDTO> settings = new ArrayList<>();
        if (todoListJson != null) {
            Gson gson = new Gson();
            Type type = new TypeToken<List<TodoItem>>() {
            }.getType();
            List<TodoItem> todoItems = gson.fromJson(todoListJson, type);

            // 转换为TodoSettingSyncDTO列表
            // 使用UTC时间以匹配服务器时区
            LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
            String timestamp = now.format(formatter);

            for (TodoItem item : todoItems) {
                TodoSettingSyncDTO setting = new TodoSettingSyncDTO();
                setting.setTitle(item.getName());
                setting.setType(item.getType());
                setting.setTimerMode(item.getSetting().getTimerMode());
                setting.setCountdownDuration(item.getCountdownDuration());
                setting.setGoalDeadline(item.getSetting().getGoalDeadline());
                setting.setGoalTargetType(item.getSetting().getGoalTargetType());
                setting.setGoalTargetValue(item.getSetting().getGoalTargetValue());
                setting.setRestDuration(item.getSetting().getRestDuration());
                setting.setCycle(item.getSetting().getCycle());
                setting.setClientCreatedAt(timestamp);
                setting.setClientUpdatedAt(timestamp);
                settings.add(setting);
            }
        }
        Log.d(TAG, "getLocalTodoSettings: 本地待办事项数量: " + settings.size());
        return settings;
    }

    /**
     * 保存从云端下载的待办事项到本地
     *
     * @param settings 从云端获取的待办事项列表
     */
    private void saveTodoSettingsToLocal(List<TodoSettingDTO> settings) {
        Log.d(TAG, "saveTodoSettingsToLocal: 保存云端待办事项到本地，数量: " + settings.size());
        SharedPreferences sharedPreferences = context.getSharedPreferences("todo_data", Context.MODE_PRIVATE);
        Gson gson = new Gson();

        List<TodoItem> todoItems = new ArrayList<>();
        for (TodoSettingDTO setting : settings) {
            TodoItem item = new TodoItem(setting);
            todoItems.add(item);
        }

        String todoListJson = gson.toJson(todoItems);
        sharedPreferences.edit().putString("todo_list", todoListJson).apply();
        Log.d(TAG, "saveTodoSettingsToLocal: 保存完成");
    }

    /**
     * 显示云同步主对话框
     * 提供"云端设定"和"上传记录"两个选项
     */
    public void showSyncDialog() {
        Log.d(TAG, "显示云同步主对话框");
        // 创建弹窗
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        View view = LayoutInflater.from(context).inflate(R.layout.dialog_cloud_sync, null);
        builder.setView(view);

        syncDialog = builder.create();

        // 设置取消按钮
        Button cancelBtn = view.findViewById(R.id.btn_cancel);
        if (cancelBtn != null) {
            cancelBtn.setOnClickListener(v -> {
                Log.d(TAG, "用户取消云同步操作");
                syncDialog.dismiss();
            });
        }

        syncDialog.show();

        // 设置弹窗中的按钮点击事件
        Button cloudSettingsBtn = view.findViewById(R.id.btn_1); // 云端设定
        Button uploadRecordsBtn = view.findViewById(R.id.btn_2); // 上传记录

        if (cloudSettingsBtn != null) {
            cloudSettingsBtn.setOnClickListener(v -> {
                Log.d(TAG, "用户选择云端设定选项");
                syncDialog.dismiss();
                fetchCloudSettings();
            });
        }

        if (uploadRecordsBtn != null) {
            uploadRecordsBtn.setOnClickListener(v -> {
                Log.d(TAG, "用户选择上传记录选项");
                syncDialog.dismiss();
                // 实现上传记录功能
                RecordUploadManager recordUploadManager = new RecordUploadManager(context);
                recordUploadManager.uploadRecords();
            });
        }
    }

    /**
     * 从服务器获取云端设定数据
     * 调用API接口获取当前用户的待办设定模板
     */
    private void fetchCloudSettings() {
        Log.d(TAG, "开始获取云端设定数据");
        String token = TokenManager.getToken(context);
        if (token == null) {
            Log.w(TAG, "用户未登录，无法获取云端设定");
            Toast.makeText(context, "用户未登录", Toast.LENGTH_SHORT).show();
            return;
        }

        ApiService apiService = ApiClient.getClient().create(ApiService.class);
        Call<Result<List<TodoSettingDTO>>> call = apiService.pullTodoSettings("Bearer " + token);

        call.enqueue(new Callback<Result<List<TodoSettingDTO>>>() {
            @Override
            public void onResponse(Call<Result<List<TodoSettingDTO>>> call, Response<Result<List<TodoSettingDTO>>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    Result<List<TodoSettingDTO>> result = response.body();
                    Log.d(TAG, "获取云端设定响应成功，状态码: " + result.getCode());
                    if (result.getCode() == 200) {
                        Log.d(TAG, "云端设定获取成功，设定数量: " + result.getData().size());
                        showCloudSettingsDetail(result.getData());
                    } else {
                        Log.w(TAG, "云端设定获取失败，错误码: " + result.getCode() + "，信息: " + result.getMessage());
                        showNoCloudData();
                    }
                } else {
                    Log.e(TAG, "获取云端设定响应失败，响应码: " + response.code());
                    showNoCloudData();
                }
            }

            @Override
            public void onFailure(Call<Result<List<TodoSettingDTO>>> call, Throwable t) {
                Log.e(TAG, "获取云端设定网络请求失败: " + t.getMessage(), t);
                showNoCloudData();
            }
        });
    }

    /**
     * 显示云端设定详情对话框
     * 当云端存在用户数据时显示此对话框，包含设定详情和操作选项
     *
     * @param settings 从云端获取的待办设定列表
     */
    private void showCloudSettingsDetail(List<TodoSettingDTO> settings) {
        Log.d(TAG, "显示云端设定详情对话框，设定数量: " + settings.size());
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        View view = LayoutInflater.from(context).inflate(R.layout.dialog_cloud_detail, null);
        builder.setView(view);

        detailDialog = builder.create();

        TextView titleText = view.findViewById(R.id.dialog_title);
        if (titleText != null) {
            titleText.setText("云端设定");
        }

        Button acceptBtn = view.findViewById(R.id.btn_1);
        Button overwriteBtn = view.findViewById(R.id.btn_2);
        Button cancelBtn = view.findViewById(R.id.btn_cancel);

        if (acceptBtn != null) {
            acceptBtn.setOnClickListener(v -> {
                Log.d(TAG, "用户选择接受云端设定（下载）");
                downloadSettings(settings);
                detailDialog.dismiss();
            });
        }

        if (overwriteBtn != null) {
            overwriteBtn.setOnClickListener(v -> {
                Log.d(TAG, "用户选择覆盖云端设定（上传）");
                uploadSettings();
                detailDialog.dismiss();
            });
        }

        if (cancelBtn != null) {
            cancelBtn.setOnClickListener(v -> {
                Log.d(TAG, "用户取消云端设定操作");
                detailDialog.dismiss();
            });
        }

        // 显示云端数据信息
        TextView infoText = view.findViewById(R.id.dialog_info);
        if (infoText != null) {
            StringBuilder info = new StringBuilder();
            info.append("设定数量: ").append(settings.size()).append("\n\n");

            info.append("设定详情:\n");
            // 显示每个待办项的名称和类型，最多显示3个
            int displayCount = Math.min(settings.size(), 3);
            for (int i = 0; i < displayCount; i++) {
                TodoSettingDTO setting = settings.get(i);
                String type = setting.getType();
                if (Objects.equals(type, "GOAL"))
                    type = "定目标";
                else
                    type = "普通番茄钟";
                info.append(setting.getTitle()).append(" (").append(type).append(")\n");
            }
            if (settings.size() > 3) {
                info.append("... 等").append(settings.size()).append("个设定\n");
            }

            infoText.setText(info.toString());
            infoText.setVisibility(View.VISIBLE);
        }

        detailDialog.show();
    }

    /**
     * 显示无云端数据对话框
     * 当用户在云端没有数据时显示此对话框，禁用下载功能
     */
    private void showNoCloudData() {
        Log.d(TAG, "显示无云端数据对话框");
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        View view = LayoutInflater.from(context).inflate(R.layout.dialog_cloud_detail, null);
        builder.setView(view);

        detailDialog = builder.create();

        TextView titleText = view.findViewById(R.id.dialog_title);
        if (titleText != null) {
            titleText.setText("云端设定");
        }

        Button acceptBtn = view.findViewById(R.id.btn_1);
        Button overwriteBtn = view.findViewById(R.id.btn_2);
        Button cancelBtn = view.findViewById(R.id.btn_cancel);

        if (acceptBtn != null) {
            acceptBtn.setText("接受云端（下载）");
            acceptBtn.setEnabled(false); // 禁用下载按钮
        }

        if (overwriteBtn != null) {
            overwriteBtn.setOnClickListener(v -> {
                Log.d(TAG, "用户选择覆盖云端设定（上传）");
                uploadSettings();
                detailDialog.dismiss();
            });
        }

        if (cancelBtn != null) {
            cancelBtn.setOnClickListener(v -> {
                Log.d(TAG, "用户取消无云端数据对话框");
                detailDialog.dismiss();
            });
        }

        TextView infoText = view.findViewById(R.id.dialog_info);
        if (infoText != null) {
            infoText.setText("云端没有设定");
            infoText.setVisibility(View.VISIBLE);
        }

        detailDialog.show();
    }

    /**
     * 上传本地设定到云端
     */
    private void uploadSettings() {
        Log.d(TAG, "开始上传本地设定到云端");
        String token = TokenManager.getToken(context);
        if (token == null) {
            Log.w(TAG, "用户未登录，无法上传设定");
            Toast.makeText(context, "用户未登录", Toast.LENGTH_SHORT).show();
            return;
        }

        List<TodoSettingSyncDTO> localSettings = getLocalTodoSettings();
        if (localSettings.isEmpty()) {
            Log.w(TAG, "本地没有待办事项");
            Toast.makeText(context, "本地没有待办事项", Toast.LENGTH_SHORT).show();
            return;
        }

        ApiService apiService = ApiClient.getClient().create(ApiService.class);
        Call<Result<Void>> call = apiService.pushTodoSettings("Bearer " + token, localSettings);

        call.enqueue(new Callback<Result<Void>>() {
            @Override
            public void onResponse(Call<Result<Void>> call, Response<Result<Void>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    Result<Void> result = response.body();
                    Log.d(TAG, "上传设定响应成功，状态码: " + result.getCode());
                    if (result.getCode() == 200) {
                        Log.d(TAG, "上传设定成功");
                        Toast.makeText(context, "上传成功", Toast.LENGTH_SHORT).show();
                    } else {
                        Log.w(TAG, "上传设定失败，错误码: " + result.getCode() + "，信息: " + result.getMessage());
                        Toast.makeText(context, "上传失败: " + result.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Log.e(TAG, "上传设定响应失败，响应码: " + response.code());
                    Toast.makeText(context, "上传失败，响应码: " + response.code(), Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<Result<Void>> call, Throwable t) {
                Log.e(TAG, "上传设定网络请求失败: " + t.getMessage(), t);
                Toast.makeText(context, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * 从云端下载设定到本地
     *
     * @param settings 从云端获取的待办设定列表
     */
    private void downloadSettings(List<TodoSettingDTO> settings) {
        Log.d(TAG, "开始从云端下载设定到本地");
        try {
            saveTodoSettingsToLocal(settings);
            Log.d(TAG, "下载设定成功");
            Toast.makeText(context, "下载成功，已更新本地设定", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Log.e(TAG, "下载设定失败: " + e.getMessage(), e);
            Toast.makeText(context, "下载失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
}
